/**
 * 全局单例类 - 用于存储非响应式的数据
 * 替换直接使用 window 对象存储数据的方式
 */
class GlobalSingleton {
  constructor() {
    // 防止重复实例化
    if (GlobalSingleton.instance) {
      return GlobalSingleton.instance
    }

    // 初始化数据存储
    this.data = new Map()

    // 事件监听器存储
    this.eventListeners = new Map()

    // 缓存存储
    this.cache = new Map()

    // 配置存储
    this.config = new Map()

    // 临时数据存储（可设置过期时间）
    this.tempData = new Map()

    // 标记实例
    GlobalSingleton.instance = this

    // 冻结实例，防止被修改
    Object.freeze(this)
  }

  /**
   * 获取单例实例
   * @returns {GlobalSingleton}
   */
  static getInstance () {
    if (!GlobalSingleton.instance) {
      GlobalSingleton.instance = new GlobalSingleton()
    }
    return GlobalSingleton.instance
  }

  // ==================== 数据存储方法 ====================

  /**
   * 设置数据
   * @param {string} key - 数据键
   * @param {*} value - 数据值
   * @param {Object} options - 选项
   * @param {number} options.expireTime - 过期时间（毫秒）
   */
  setData (key, value, options = {}) {
    if (options.expireTime) {
      // 存储到临时数据中，带过期时间
      this.tempData.set(key, {
        value,
        expireTime: Date.now() + options.expireTime
      })
    } else {
      // 存储到永久数据中
      this.data.set(key, value)
    }
  }

  /**
   * 获取数据
   * @param {string} key - 数据键
   * @param {*} defaultValue - 默认值
   * @returns {*}
   */
  getData (key, defaultValue = null) {
    // 先检查临时数据
    if (this.tempData.has(key)) {
      const tempItem = this.tempData.get(key)
      if (Date.now() < tempItem.expireTime) {
        return tempItem.value
      } else {
        // 数据已过期，删除
        this.tempData.delete(key)
      }
    }

    // 检查永久数据
    return this.data.get(key) ?? defaultValue
  }

  /**
   * 删除数据
   * @param {string} key - 数据键
   */
  removeData (key) {
    this.data.delete(key)
    this.tempData.delete(key)
  }

  /**
   * 检查数据是否存在
   * @param {string} key - 数据键
   * @returns {boolean}
   */
  hasData (key) {
    // 检查临时数据
    if (this.tempData.has(key)) {
      const tempItem = this.tempData.get(key)
      if (Date.now() < tempItem.expireTime) {
        return true
      } else {
        this.tempData.delete(key)
      }
    }

    return this.data.has(key)
  }

  /**
   * 清除所有数据
   */
  clearData () {
    this.data.clear()
    this.tempData.clear()
  }

  // ==================== 缓存管理方法 ====================

  /**
   * 设置缓存
   * @param {string} key - 缓存键
   * @param {*} value - 缓存值
   * @param {number} ttl - 生存时间（毫秒）
   */
  setCache (key, value, ttl = 30 * 60 * 1000) { // 默认30分钟
    this.cache.set(key, {
      value,
      timestamp: Date.now(),
      ttl
    })
  }

  /**
   * 获取缓存
   * @param {string} key - 缓存键
   * @returns {*}
   */
  getCache (key) {
    if (!this.cache.has(key)) {
      return null
    }

    const cacheItem = this.cache.get(key)
    const now = Date.now()

    if (now - cacheItem.timestamp > cacheItem.ttl) {
      // 缓存已过期
      this.cache.delete(key)
      return null
    }

    return cacheItem.value
  }

  /**
   * 删除缓存
   * @param {string} key - 缓存键
   */
  removeCache (key) {
    this.cache.delete(key)
  }

  /**
   * 清除所有缓存
   */
  clearCache () {
    this.cache.clear()
  }

  /**
   * 清除过期缓存
   */
  clearExpiredCache () {
    const now = Date.now()
    for (const [key, item] of this.cache.entries()) {
      if (now - item.timestamp > item.ttl) {
        this.cache.delete(key)
      }
    }
  }

  /**
   * 获取缓存统计信息
   * @returns {Object}
   */
  getCacheStats () {
    const totalSize = Array.from(this.cache.values()).reduce((sum, item) => {
      return sum + (JSON.stringify(item.value).length || 0)
    }, 0)

    return {
      count: this.cache.size,
      totalSize,
      averageSize: this.cache.size > 0 ? Math.round(totalSize / this.cache.size) : 0
    }
  }

  // ==================== 配置管理方法 ====================

  /**
   * 设置配置
   * @param {string} key - 配置键
   * @param {*} value - 配置值
   */
  setConfig (key, value) {
    this.config.set(key, value)
  }

  /**
   * 获取配置
   * @param {string} key - 配置键
   * @param {*} defaultValue - 默认值
   * @returns {*}
   */
  getConfig (key, defaultValue = null) {
    return this.config.get(key) ?? defaultValue
  }

  /**
   * 删除配置
   * @param {string} key - 配置键
   */
  removeConfig (key) {
    this.config.delete(key)
  }

  /**
   * 获取所有配置
   * @returns {Object}
   */
  getAllConfig () {
    return Object.fromEntries(this.config)
  }

  // ==================== 事件系统方法 ====================

  /**
   * 添加事件监听器
   * @param {string} eventName - 事件名称
   * @param {Function} callback - 回调函数
   * @param {Object} options - 选项
   */
  addEventListener (eventName, callback, options = {}) {
    if (!this.eventListeners.has(eventName)) {
      this.eventListeners.set(eventName, [])
    }

    const listener = {
      callback,
      once: options.once || false,
      id: Date.now() + Math.random()
    }

    this.eventListeners.get(eventName).push(listener)
    return listener.id
  }

  /**
   * 移除事件监听器
   * @param {string} eventName - 事件名称
   * @param {number|Function} callbackOrId - 回调函数或监听器ID
   */
  removeEventListener (eventName, callbackOrId) {
    if (!this.eventListeners.has(eventName)) {
      return
    }

    const listeners = this.eventListeners.get(eventName)
    const index = listeners.findIndex(listener =>
      listener.callback === callbackOrId || listener.id === callbackOrId
    )

    if (index > -1) {
      listeners.splice(index, 1)
    }
  }

  /**
   * 触发事件
   * @param {string} eventName - 事件名称
   * @param {*} data - 事件数据
   */
  dispatchEvent (eventName, data = null) {
    if (!this.eventListeners.has(eventName)) {
      return
    }

    const listeners = this.eventListeners.get(eventName)
    const toRemove = []

    listeners.forEach((listener, index) => {
      try {
        listener.callback(data)
        if (listener.once) {
          toRemove.push(index)
        }
      } catch (error) {
        console.error(`事件监听器执行错误 [${eventName}]:`, error)
      }
    })

    // 移除一次性监听器
    toRemove.reverse().forEach(index => {
      listeners.splice(index, 1)
    })
  }

  /**
   * 移除所有事件监听器
   * @param {string} eventName - 事件名称（可选）
   */
  removeAllEventListeners (eventName = null) {
    if (eventName) {
      this.eventListeners.delete(eventName)
    } else {
      this.eventListeners.clear()
    }
  }

  // ==================== 工具方法 ====================

  /**
   * 获取所有数据的键
   * @returns {Array}
   */
  getAllKeys () {
    const dataKeys = Array.from(this.data.keys())
    const tempKeys = Array.from(this.tempData.keys()).filter(key => {
      const item = this.tempData.get(key)
      return Date.now() < item.expireTime
    })
    return [...new Set([...dataKeys, ...tempKeys])]
  }

  /**
   * 获取存储统计信息
   * @returns {Object}
   */
  getStats () {
    // 清理过期的临时数据
    const now = Date.now()
    for (const [key, item] of this.tempData.entries()) {
      if (now >= item.expireTime) {
        this.tempData.delete(key)
      }
    }

    return {
      dataCount: this.data.size,
      tempDataCount: this.tempData.size,
      cacheCount: this.cache.size,
      configCount: this.config.size,
      eventListenerCount: Array.from(this.eventListeners.values()).reduce((sum, listeners) => sum + listeners.length, 0)
    }
  }

  /**
   * 清除所有数据（包括缓存、配置、事件监听器）
   */
  clearAll () {
    this.data.clear()
    this.tempData.clear()
    this.cache.clear()
    this.config.clear()
    this.eventListeners.clear()
  }

  /**
   * 导出数据（用于调试）
   * @returns {Object}
   */
  exportData () {
    return {
      data: Object.fromEntries(this.data),
      tempData: Object.fromEntries(this.tempData),
      cache: Object.fromEntries(this.cache),
      config: Object.fromEntries(this.config),
      stats: this.getStats()
    }
  }
}

// 创建单例实例
const globalSingleton = GlobalSingleton.getInstance()

// 在开发环境下，将单例挂载到 window 对象上以便调试（仅在非插件模式下）
if (process.env.NODE_ENV === 'development' && typeof window !== 'undefined') {
  // 这里不直接挂载，让插件来处理
}

// ==================== Vue 插件功能 ====================

/**
 * Vue 插件安装函数
 * @param {Object} app - Vue 应用实例
 * @param {Object} options - 插件选项
 */
const install = (app, options = {}) => {
  // 合并默认配置
  const defaultOptions = {
    globalPropertyName: '$globalSingleton', // 全局属性名
    provideKey: 'globalSingleton', // provide/inject 的键名
    enableDevtools: process.env.NODE_ENV === 'development' // 是否启用开发工具
  }

  const pluginOptions = { ...defaultOptions, ...options }

  // 设置初始配置
  if (options.config) {
    Object.entries(options.config).forEach(([key, value]) => {
      globalSingleton.setConfig(key, value)
    })
  }

  // 将单例添加到全局属性，使组件可以通过 this.$globalSingleton 访问
  app.config.globalProperties[pluginOptions.globalPropertyName] = globalSingleton

  // 通过 provide 提供单例，使组件可以通过 inject 访问
  app.provide(pluginOptions.provideKey, globalSingleton)

  // 在开发环境下，将单例挂载到 window 对象上以便调试
  if (pluginOptions.enableDevtools) {
    window.globalSingleton = globalSingleton
    console.log('🔧 GlobalSingleton 已注册到 window.globalSingleton，可在控制台中调试')
  }

  console.log(`✅ GlobalSingleton 插件已安装，可通过 ${pluginOptions.globalPropertyName} 访问`)
}

// Vue 插件对象
const GlobalSingletonPlugin = {
  install,
  // 提供单例实例的直接访问
  getInstance: () => globalSingleton
}

// ==================== Composition API 支持 ====================

/**
 * Composition API 钩子函数
 * 在 setup() 中使用，自动获取全局单例实例
 * @returns {GlobalSingleton}
 */
export const useGlobalSingleton = () => {
  // 尝试从 Vue 实例中获取
  if (typeof window !== 'undefined' && typeof getCurrentInstance === 'function') {
    try {
      const { getCurrentInstance } = require('vue')
      const instance = getCurrentInstance()
      if (instance && instance.appContext.config.globalProperties.$globalSingleton) {
        return instance.appContext.config.globalProperties.$globalSingleton
      }
    } catch (e) {
      // 如果获取失败，继续使用单例实例
    }
  }

  // 备用方案：直接返回单例实例
  return globalSingleton
}

// ==================== 更优雅的 Composition API Hook ====================

/**
 * 增强版 Composition API 钩子
 * 自动检测 Vue 环境并获取全局单例
 * @returns {GlobalSingleton}
 */
export const useGlobal = () => {
  // 在 Vue 3 环境中，尝试从当前实例获取
  if (typeof window !== 'undefined' && window.Vue) {
    try {
      const { getCurrentInstance, inject } = window.Vue
      const instance = getCurrentInstance()

      if (instance) {
        // 尝试通过 inject 获取
        const injectedSingleton = inject('globalSingleton', null)
        if (injectedSingleton) {
          return injectedSingleton
        }

        // 尝试通过全局属性获取
        const globalProperty = instance.appContext.config.globalProperties.$globalSingleton
        if (globalProperty) {
          return globalProperty
        }
      }
    } catch (e) {
      // 静默失败，使用备用方案
    }
  }

  // 备用方案：直接返回单例实例
  return globalSingleton
}

// ==================== 自动导入支持 ====================

/**
 * 全局安装函数 - 支持自动导入
 * 可以在 vite.config.js 中配置自动导入
 */
export const $global = globalSingleton

// ==================== 导出 ====================

// 默认导出插件（推荐在 main.js 中使用）
export default GlobalSingletonPlugin

// 命名导出，提供更多灵活性
export { globalSingleton, GlobalSingleton }

// ==================== TypeScript 类型声明支持 ====================
// 如果项目使用 TypeScript，可以添加以下类型声明

/*
// 在项目的 types 目录下创建 global-singleton.d.ts 文件
declare module '@vue/runtime-core' {
  interface ComponentCustomProperties {
    $globalSingleton: GlobalSingleton
  }
}

export interface GlobalSingletonOptions {
  globalPropertyName?: string
  provideKey?: string
  enableDevtools?: boolean
  config?: Record<string, any>
}
*/
